#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <linux/fb.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <sys/ioctl.h>

#include <disp_manager.h>


static int fd_fb;
static struct fb_var_screeninfo var;	/* Current var */
static int screen_size;
static unsigned char *fb_base;
static unsigned int line_width;
static unsigned int pixel_width;

static int FB_DeviceInit(void){

    fd_fb = open("/dev/fb0", O_RDWR);
	if (fd_fb < 0)
	{
		printf("Can't open /dev/fb0\n");
		return -1;
	}
	if (ioctl(fd_fb, FBIOGET_VSCREENINFO, &var))
	{
		printf("Get var failed.\n");
		return -1;
	}

	line_width  = var.xres * var.bits_per_pixel / 8;
	pixel_width = var.bits_per_pixel / 8;
	screen_size = var.xres * var.yres * var.bits_per_pixel / 8;
	fb_base = (unsigned char *)mmap(NULL , screen_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd_fb, 0);
	if (fb_base == (unsigned char *)-1)
	{
		printf("Mmap failed.\n");
		return -1;
	}

    return 0;
}



static int FB_DeviceExit(void){

    munmap(fb_base , screen_size);
	close(fd_fb);
    
    return 0;
}


// 将Framebuffer中获取的参数存到ptDispBuff中
static int FB_GetBuffer(PDispBuff ptDispBuff)
{
	ptDispBuff->iXres = var.xres;
	ptDispBuff->iYres = var.yres;
	ptDispBuff->iBpp  = var.bits_per_pixel;
	ptDispBuff->buff  = fb_base;
	return 0;
}


static int FB_FlushRegion(PRegion ptRegion, PDispBuff ptDispBuff)
{
	return 0;
}



static struct DispOpr g_tFramebufferOpr = {
    
    .name = "Framebuffer",
    .DeviceInit = FB_DeviceInit,
    .DeviceExit = FB_DeviceExit,
    .GetBuffer = FB_GetBuffer,
    .FlushRegion = FB_FlushRegion,

};


void RegisterFBtoDeviceList(void){

	// g_tFramebufferOpr调用注册DispOpr函数
	RegisterDispDevice(&g_tFramebufferOpr);
}